package com.szeldon.declatest.reports.plugins;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import nu.xom.Document;
import nu.xom.Element;
import nu.xom.ParsingException;
import nu.xom.ValidityException;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.szeldon.declatest.declaration.TestsSuiteDeclaration;
import com.szeldon.declatest.exec.TestSuiteExecHistory;
import com.szeldon.declatest.exec.events.IfConditionEvaluationEndExecEvent;
import com.szeldon.declatest.exec.events.IfConditionEvaluationStartExecEvent;
import com.szeldon.declatest.exec.events.ScenarioExecutionEndExecEvent;
import com.szeldon.declatest.exec.events.ScenarioExecutionStartExecEvent;
import com.szeldon.declatest.exec.events.dostep.DoScenarioStepEndExecEvent;
import com.szeldon.declatest.exec.events.dostep.DoScenarioStepStartExecEvent;
import com.szeldon.declatest.exec.events.dostep.jms.JmsMessageReceivedExecEvent;
import com.szeldon.declatest.exec.events.dostep.jms.JmsMessageSentExecEvent;
import com.szeldon.declatest.exec.result.EndScenarioExecutionResult;
import com.szeldon.declatest.reports.ReportGenerator;
import com.szeldon.declatest.reports.ReportGeneratorTest;
import com.szeldon.declatest.reports.exceptions.GeneratingReportException;

/**
 * Tests for a plugin generating reports in HTML format.
 * 
 * TODO: currently those tests aren't checking anything more than mere existence of HTML files. It's like that because
 * of less and lesser time left to complete the first version of the whole Declatest.
 * 
 * @author szeldon
 * 
 */
public class HtmlReportGeneratorPluginTest {

    private static final String HTML_REPORTS_OUTPUT_DIRECTORY = "output/reports/plugins/html/";

    private ReportGenerator generator = null;
    private TestsSuiteDeclaration suite = null;
    private TestSuiteExecHistory history = null;
    private Properties properties = null;
    private String testSuiteId;
    private String testSuiteDescription;

    @BeforeTest
    public void beforeTest() throws IOException {
        // inits attributes for generator
        testSuiteId = "testSuiteId";
        testSuiteDescription = "testSuiteDescription";
        suite = new TestsSuiteDeclaration();
        suite.addTestSuiteAttribute("id", testSuiteId);
        suite.addTestSuiteAttribute("description", testSuiteDescription);
        history = new TestSuiteExecHistory(testSuiteId);
        properties = new Properties();

        // creates and uses generator
        generator = new ReportGenerator();
        generator.addGeneratorPlugin(new HtmlReportGeneratorPlugin());
    }

    @Test
    public void emptyTestSuiteTest() throws IOException, ValidityException, ParsingException, GeneratingReportException {

        generator.generateReport(suite, history, properties, ReportGeneratorTest.TEST_REPORT_XML_DATA_OUTPUT_DIRECTORY,
                ReportGeneratorTest.TEST_REPORT_PLUGINS_OUTPUT_DIRECTORY);

        // checks if there's a simple empty tag for test suite and nothing else
        File file = ReportGeneratorTest.checkIfOneXmlExists();
        Document document = ReportGeneratorTest.readFileIntoDocument(file);
        Element root = document.getRootElement();
        Assert.assertEquals(root.getLocalName(), ReportGeneratorTest.REPORT_TAG_FOR_TEST_SUITE);
        Assert.assertEquals(root.getAttributeCount(), 2);
        Assert.assertEquals(root.getAttributeValue("id"), testSuiteId);
        Assert.assertEquals(root.getAttributeValue("description"), testSuiteDescription);
        Assert.assertEquals(root.getChildCount(), 0);

        // cleans after itself... deletes report
        file.delete();
    }

    @Test
    public void simpleScenarioTest() throws IOException, GeneratingReportException {
        String scenarioId = "scenarioId";
        String someEventDescription = "someEventDescription";
        String stepId = "stepId";
        String stepDescription = "stepDescription";
        String stepEndpointId = "stepEndpointId";
        String stepRequestPath = ReportGeneratorTest.TESTS_RESOURCES_DIRECTORY
                + ReportGeneratorTest.TESTS_REQUESTS_RESPONSES_DIRECTORY + "request01.xml";
        String stepResponsePath = ReportGeneratorTest.TESTS_RESOURCES_DIRECTORY
                + ReportGeneratorTest.TESTS_REQUESTS_RESPONSES_DIRECTORY + "response01.xml";
        String endpointDescription = "endpointDescription";
        String endpointUrl = "example.com";
        String endpointSettingsId = "endpointSettingsId";
        String left = "leftPart";
        String operator = "operator";
        String right = "rightPart";
        String descriptionForIf = "descriptionForIf";
        String leftEvaluated = "leftEvaluatedPart";
        String rightEvaluated = "rightEvaluatedPart";
        boolean isEvaluated = true;
        history.addExecEvent(new ScenarioExecutionStartExecEvent(scenarioId, someEventDescription, new Date()));
        history.addExecEvent(new IfConditionEvaluationStartExecEvent(scenarioId, someEventDescription, new Date(),
                left, operator, right, descriptionForIf));
        history.addExecEvent(new IfConditionEvaluationEndExecEvent(scenarioId, someEventDescription, new Date(),
                leftEvaluated, operator, rightEvaluated, descriptionForIf, isEvaluated));
        history.addExecEvent(new DoScenarioStepStartExecEvent(scenarioId, someEventDescription, new Date(), stepId,
                stepDescription, stepEndpointId, stepRequestPath, endpointDescription, endpointUrl, endpointSettingsId));
        history.addExecEvent(new JmsMessageSentExecEvent(scenarioId, someEventDescription, new Date(), stepId,
                "stepDescription", "stepEndpointId", "stepRequestPath", "endpointDescription", "endpointUrl",
                "endpointSettingsId", "queue", "queueName", ReportGeneratorTest.getFileContent(stepRequestPath)));
        history.addExecEvent(new JmsMessageReceivedExecEvent(scenarioId, someEventDescription, new Date(), stepId,
                "stepDescription", "stepEndpointId", "stepRequestPath", "endpointDescription", "endpointUrl",
                "endpointSettingsId", "queue", "queueName", ReportGeneratorTest.getFileContent(stepResponsePath)));
        history.addExecEvent(new DoScenarioStepEndExecEvent(scenarioId, someEventDescription, new Date(), stepId,
                stepDescription, stepEndpointId, stepRequestPath, endpointDescription, endpointUrl, endpointSettingsId));
        history.addExecEvent(new ScenarioExecutionEndExecEvent(scenarioId, someEventDescription, new Date(),
                new EndScenarioExecutionResult(null)));
        generator.generateReport(suite, history, properties, ReportGeneratorTest.TEST_REPORT_XML_DATA_OUTPUT_DIRECTORY,
                ReportGeneratorTest.TEST_REPORT_PLUGINS_OUTPUT_DIRECTORY);

        File xmlFile = ReportGeneratorTest.checkIfOneXmlExists();
        File htmlFile = checkIfOneHtmlExists();

        // cleans after itself
        xmlFile.delete();
        htmlFile.delete();
    }

    public static File checkIfOneHtmlExists() {
        return ReportGeneratorTest.checkIfOneFileWithExtensionExistsInDirectory(".html", HTML_REPORTS_OUTPUT_DIRECTORY);
    }

}
